﻿using fabao.Common.Entity;
using fabao.Common.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;

namespace fabao.Common.Util
{
    public class HttpHelper
    {
        private static readonly IHttpClientFactory _clientFactory;
        private static string clientname = ConfigSettings.Get<string>("HttpClientName");
        static HttpHelper()
        {
            _clientFactory= ServiceLocator.Provider.GetRequiredService<IHttpClientFactory>();
        }



        /// <summary>
        /// form-data post异步请求
        /// </summary>
        /// <param name="url">请求路径</param>
        /// <param name="paramslist">参数</param>
        /// <param name="content">返回消息</param>
        /// <returns></returns>
        public static async Task<ExeMsgInfo> PostFormDataAsync(string url,Dictionary<string, object> paramslist)
        {
            ExeMsgInfo exe = new ExeMsgInfo() { RetValue = "", RetStatus = 200 };
            try
            {
                var content = new MultipartFormDataContent();
                foreach (var item in paramslist)
                {
                    if(item.Key == "sign" || item.Key == "timestamp")
                    {
                        content.Headers.Add(item.Key, item.Value.ToString());
                        continue;
                    }
                    if (item.Value==null)
                    {
                        content.Add(new StringContent(""), item.Key);
                    }
                    else
                    {
                        content.Add(new StringContent(item.Value.ToString()), item.Key);
                    }
                  
                }
                 //发送请求
                 var response = await _clientFactory.CreateClient(clientname).PostAsync(url, content);

                if (response.IsSuccessStatusCode)
                {
                    exe.RetValue = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    exe.RetStatus = 500;
                    exe.RetValue = $"请求失败：状态码：{response.StatusCode}，失败原因：{response.ReasonPhrase}\nUrl：{url} param:{paramslist.ToJson()}";
                }
            }
            catch (HttpRequestException ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"异常msg：{ex.Message}；该异常为：由于基础问题（如网络连接性、DNS 失败、服务器证书验证或超时），请求失败\nUrl：{url} param:{paramslist.ToJson()}";
            }
            catch (Exception ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"异常msg：{ex.Message}；异常堆栈信息：{ex.StackTrace}，请求失败\nUrl：{url} param:{paramslist.ToJson()}";
            }
            return exe;
        }
        public static async Task<ExeMsgInfo> PostFormUrlAsync(string url, Dictionary<string, string> data)
        {
            ExeMsgInfo exe = new ExeMsgInfo() { RetValue = "", RetStatus = 200 };
            try
            {
                var content = new  FormUrlEncodedContent(data);
                //发送请求
                var response = await _clientFactory.CreateClient(clientname).PostAsync(url, content);

                if (response.IsSuccessStatusCode)
                {
                    exe.RetValue = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    exe.RetStatus = 500;
                    exe.RetValue = $"请求失败：状态码：{response.StatusCode}，失败原因：{response.ReasonPhrase}\nUrl：{url} param:{data.ToJson()}";
                }
            }
            catch (HttpRequestException ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"异常msg：{ex.Message}；该异常为：由于基础问题（如网络连接性、DNS 失败、服务器证书验证或超时），请求失败\nUrl：{url} param:{data.ToJson()}";
            }
            catch (Exception ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"异常msg：{ex.Message}；异常堆栈信息：{ex.StackTrace}，请求失败\nUrl：{url} param:{data.ToJson()}";
            }
            return exe;
        }
        /// <summary>
        /// 发送post请求 json
        /// </summary>
        /// <param name="url"></param>
        /// <param name="paramobj"></param>
        /// <param name="setTimeOutSecond">自定义超时（秒）</param>
        /// <returns></returns>
        public static async Task<ExeMsgInfo> PostJsonAsync(string url, object paramobj,string sign = "",string timeStamp = "",int setTimeOutSecond = 0)
        {
            ExeMsgInfo exe = new ExeMsgInfo() { RetValue = "", RetStatus = 200 };
            string param = "";
            try
            {
                param = JsonConvert.SerializeObject(paramobj);

                var content = new StringContent(param, Encoding.UTF8, "application/json");
                if (!string.IsNullOrWhiteSpace(sign) && !string.IsNullOrWhiteSpace(timeStamp))
                {
                    content.Headers.Add("sign", sign);
                    content.Headers.Add("timestamp", timeStamp);
                }
                var client = _clientFactory.CreateClient(clientname);

                //设置超时
                if (setTimeOutSecond > 0)
                {
                    client.Timeout = TimeSpan.FromSeconds(setTimeOutSecond);
                }

                var response = await client.PostAsync(url, content);

                exe.RetStatus = (int)response.StatusCode;

                if (response.IsSuccessStatusCode)
                {
                    exe.RetValue = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    exe.RetStatus = 500;
                    exe.RetValue = $"请求失败：状态码：{response.StatusCode}，原因：{response.ReasonPhrase}\nUrl：{url} param:{param}";
                }

                return exe;
            }
            catch (HttpRequestException ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"异常msg：{ex.Message}；该异常为：由于基础问题（如网络连接性、DNS 失败、服务器证书验证或超时），请求失败\nUrl：{url} param:{param}";
                return exe;
            }
            catch (Exception ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"{ex.Message}\nUrl：{url} param：{param}";
                return exe;
            }
        }
        /// <summary>
        /// 发起GET异步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static async Task<ExeMsgInfo> GetUrlAsync(string url, string contentType = null, Dictionary<string, string> headers = null)
        {
            ExeMsgInfo exe = new ExeMsgInfo() { RetValue = "", RetStatus = 200 };
            var client = _clientFactory.CreateClient(clientname);
            if (contentType != null)
                client.DefaultRequestHeaders.Add("ContentType", contentType);
            if (headers != null)
            {
                foreach (var header in headers)
                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
            }
            try
            {
                HttpResponseMessage response = await client.GetAsync(url);
                exe.RetStatus = (int)response.StatusCode;
                exe.RetValue = await response.Content.ReadAsStringAsync();
                return exe;
            }
            catch (HttpRequestException ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"异常msg：{ex.Message}；该异常为：由于基础问题（如网络连接性、DNS 失败、服务器证书验证或超时），请求失败\nUrl：{url}";
                return exe;
            }
            catch (Exception ex)
            {
                exe.RetStatus = 500;
                exe.RetValue = $"{ex.Message}\nUrl：{url}";
                return exe;
            }

        }
        /// <summary>
        /// 异步Get请求转为字节
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        /// <exception cref="HttpRequestException"></exception>
        public static async Task<byte[]> GetUrlToBytesAsync(string url) 
        {
            var response= await _clientFactory.CreateClient(clientname).GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsByteArrayAsync();
            }
            else
            {
                throw new HttpRequestException($"Error: {response.StatusCode}");
            }
        }

        public static async Task<Stream> GetStreamAsync(string url) 
        {
            var stream=  await _clientFactory.CreateClient(clientname).GetStreamAsync(url);
            return stream;
        }

        /// <summary>
        /// 获取绝对路径
        /// </summary>
        /// <param name="refer"></param>
        /// <returns></returns>
        public static string GetAbsoluteUri(string refer)
        {
            if (!string.IsNullOrWhiteSpace(refer))
            {
                if (Uri.TryCreate(refer, UriKind.Absolute, out var refererUri))
                {
                    return refererUri.AbsoluteUri;
                }
            }
            return null;
        }
        /// <summary>
        /// 获取IP地址
        /// </summary>
        /// <returns></returns>
        public static string GetClientIp()
        {
            //nginx方式
            string ip = Storage.Current.HttpContext.Request.Headers["X-Real-IP"].ToString();
            if (!ip.Contains("::1") && !ip.Contains("127.0.0.1") && !string.IsNullOrWhiteSpace(ip))
            {
                return ip;
            }
            ip = Storage.Current.HttpContext.Request.Headers["X-Forwarded-For"].ToString();
            if (!ip.Contains("::1") && !ip.Contains("127.0.0.1") && !string.IsNullOrWhiteSpace(ip))
            {
                return ip;
            }
            else
            {
                ip = Storage.Current.HttpContext.Connection.RemoteIpAddress.ToString();
            }
            return ip;
        }
        public static string GetRequestUrl() 
        {
            return Storage.Current.HttpContext.Request.Path;
        }
    }

    
}
